/**
 * 
 */
package com.shangdiao.sd_server.util;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.PropertyFilter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.shangdiao.sd_server.pojo.Row;
/**
 * @author syyang json���?����
 */
public class JsonUtil {
	private final static Log logger = LogFactory.getLog(JsonUtil.class);

	/**
	 * ��json��ʽ���ַ�ת����Row
	 * 
	 * @param json
	 * @return
	 */
	public static Row strToRow(String json) {
		if (json == null || json.length() == 0)
			return new Row();
		JSONObject jsonObj = JSONObject.fromObject(json);
		Row row = new Row();
		for (Object key : jsonObj.keySet()) {
			row.put(key, jsonObj.get(key));
		}
		return row;
		// return (Row)JSONObject.toBean(jsonObj, Row.class);
	}

	/**
	 * ��Rowת����json��ʽ���ַ�
	 * 
	 * @param row
	 * @return
	 */
	public static String rowToJson(Row row) {
		if (row == null || row.size() == 0)
			return "{}";
		JSONObject json = JSONObject.fromObject(row);
		return json.toString().replaceAll("'", "\\\\'");
	}

	/**
	 * ʹ��jackson������ת��Ϊjson�ַ�
	 * 
	 * */
	public static String objectToJsonStr(Object o) {
		try {
			ObjectMapper mapper = new ObjectMapper();
			return mapper.writeValueAsString(o);
		} catch (Exception e) {
			logger.error("jsonת��ʧ��," + o, e);
			return null;
		}
	}

	/**
	 * ��datainfo�ֶ���ӵ�row
	 * 
	 * @param row
	 * @return
	 */
	public static Row readDataInfo(Row row) {
		return readDataInfoBase(row, "datainfo");
	}

	/**
	 * ��ָ�����͵�JSON�ֶδ����Map
	 * 
	 * @param row
	 * @param infoName
	 * @return
	 */
	public static Row readDataInfoBase(Row row, String infoName) {
		if (row == null)
			return new Row();
		Row jsonRow = strToRow(row.gets(infoName));
		for (int i = 0; i < jsonRow.length(); i++) {
			if (!row.containsKey(jsonRow.getKey(i))) {
				row.put(jsonRow.getKey(i), jsonRow.get(i));
			}
		}
		if (row.containsKey(infoName)) {
			row.remove(infoName);
		}
		return row;
	}

	/**
	 * �Ѷ���ת��ΪJSON����
	 * 
	 * @param o
	 * @return
	 */
	public static JSON toJson(Object o) {
		return JSONObject.fromObject(o);
	}

	/**
	 * ��ָ�������Դ���datainfo�ֶ���ȥ,����row���Խ���tʽ���
	 * 
	 * @param row
	 * @return
	 */
	public static Row writeDataInfo(Row row, String[] props) {
		Row dataInfo = new Row();
		// ��ָ�������Զs�4��������dataInfo
		for (String prop : props) {
			if (row.get(prop) != null) {
				dataInfo.put(prop, row.get(prop));
				row.remove(prop);
			}
		}
		row.put("datainfo", toJson(dataInfo).toString());
		return row;
	}

	/**
	 * ��һ��JSON�������������ַ�ת��ΪList
	 * 
	 * @param str
	 * @return
	 */
	public static List strToList(String str) {
		JSONArray json = JSONArray.fromObject(str);
		List listData = (List) JSONArray.toList(json, HashMap.class);
		return listData;
	}

	public static List strToList(String str, Class class1) {
		JSONArray json = JSONArray.fromObject(str);
		List listData = null;
		try {
			listData = (List) JSONArray.toList(json, class1);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return listData;
	}

	/**
	 * ��listת��ΪJSON�����ַ�����
	 * 
	 * @param list
	 * @return
	 */
	public static String listToStr(List list) {
		if (list == null || list.size() == 0)
			return "[]";
		JSONArray jsons = JSONArray.fromObject(list, filterConfig());
		return jsons.toString();
	}

	/**
	 * ת������json
	 * 
	 * @param o
	 * @param excludeProperty
	 *            ,Ҫ�ų������
	 * @return
	 */
	public static JSON jsonExclude(Object o, String[] excludeProperty) {
		return baseJson(o, excludeProperty, true);
	}

	/**
	 * ת������JOSN
	 * 
	 * @param o
	 * @param includeProperty
	 *            ,Ҫ�������
	 * @return
	 */
	public static JSON jsonInclude(Object o, String[] includePropertys) {
		return baseJson(o, includePropertys, false);
	}

	/**
	 * ת������JOSN
	 * 
	 * @param o
	 * @param includeProperty
	 *            ,Ҫ�������
	 * @return
	 */
	public static JSON jsonListInclude(List list, String[] includePropertys) {
		return baseListJson(list, includePropertys, false);
	}

	/**
	 * ת������json
	 * 
	 * @param o
	 * @param excludeProperty
	 *            ,Ҫ�ų������
	 * @return
	 */
	public static JSON jsonListExclude(List list, String[] excludeProperty) {
		return baseListJson(list, excludeProperty, true);
	}

	/**
	 * ��ָ����ʽ����JSON����ֶ�
	 * 
	 * @param o
	 * @param excludeProperty
	 * @param exclude
	 * @return
	 */
	private static JSON baseJson(Object o, String[] excludeProperty,
			boolean exclude) {
		JSON json = JSONSerializer.toJSON(o,
				filterConfig(excludeProperty, exclude));
		return json;
	}

	/**
	 * ��ָ���ķ�ʽ�������鲢ת����JSON����
	 * 
	 * @param list
	 * @param includePropertys
	 * @param exclude
	 * @return
	 */
	private static JSON baseListJson(List list, String[] includePropertys,
			boolean exclude) {
		JSON json = JSONArray.fromObject(list,
				filterConfig(includePropertys, exclude));
		return json;
	}

	/**
	 * ���ع��������
	 * 
	 * @param propertys
	 * @param exclude
	 * @return
	 */
	private static JsonConfig filterConfig(String[] propertys, boolean exclude) {
		JsonConfig config = new JsonConfig();
		// config.setExcludes(excludeProperty);
		NamedPropertyFilter filter = new NamedPropertyFilter(propertys);
		filter.setExclude(exclude);
		// config.setJavaPropertyFilter(filter);
		config.setJsonPropertyFilter(filter);
		return config;
	}

	private static JsonConfig filterConfig() {
		JsonConfig config = new JsonConfig();
		JsonValueProcessor jp = new DateJsonValueProcessor(
				"yyyy-MM-dd HH:mm:ss");
		config.registerJsonValueProcessor(java.sql.Timestamp.class, jp);
		return config;
	}

	// ����ƹ�������
	private static class NamedPropertyFilter implements PropertyFilter {
		private String[] names;
		private boolean exclude = true;

		public void setExclude(boolean exclude) {
			this.exclude = exclude;
		}

		public NamedPropertyFilter(String[] names) {
			this.names = names;
		}

		public NamedPropertyFilter(String[] names, boolean exclude) {
			this.names = names;
			this.exclude = exclude;
		}

		public boolean apply(Object source, String property, Object value) {
			if (names == null || names.length < 1) {
				return !exclude;
			}
			for (String name : names) {
				if (name.equals(property)) {
					return exclude;
				}
			}
			return !exclude;
		}
	}

	private static class DateJsonValueProcessor implements JsonValueProcessor {
		public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
		private DateFormat dateFormat;

		/**
		 * ���췽��.
		 * 
		 * @param datePattern
		 *            ���ڸ�ʽ
		 */
		public DateJsonValueProcessor(String datePattern) {
			try {
				dateFormat = new SimpleDateFormat(datePattern);
			} catch (Exception ex) {
				dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
			}
		}

		public Object processArrayValue(Object value, JsonConfig jsonConfig) {
			return process(value);
		}

		public Object processObjectValue(String key, Object value,
				JsonConfig jsonConfig) {
			return process(value);
		}

		private Object process(Object value) {
			return dateFormat.format((java.sql.Timestamp) value);
		}
	}

	/**
	 * ʹ��jackson��json��ʽ����ת��ΪRow����
	 * */
	public static Row[] strToRowArray(String json) throws JsonMappingException,
			IOException {
		ObjectMapper mapper = new ObjectMapper();
		Row[] result = mapper.readValue(json, Row[].class);
		return result;
	}
}
